const arr = [1, 2, 2, NaN, NaN, undefined, undefined, "undefined", {}, {}, true, true, false]
// 1、Set()+Array.from()
// NaN和undefined可以去掉，尽管NaN !== NaN，但在Set中NaN被认为是相同的值
function methods1(arr) {
    const result = Array.from(new Set(arr))
    return result
}
// console.log(methods1(arr));
// 2、两层循环+splice
// 无法去重NaN和引用类型的值
function methods2(arr) {
    let len = arr.length
    for(let i = 0; i < len - 1; i++) {
        for(let j = i + 1; j < len; j++) {
            if(arr[i] === arr[j]) {
                arr.splice(j ,1)
                len--
                j--
            }
        }
    }
    return arr
}
// console.log(methods2(arr));
// 3、indexOf NaN和引用类型的值无法去掉
function methods3(arr) {
    const result = []
    arr.forEach(item => {
        if(result.indexOf(item) === -1) {
            result.push(item)
        }
    })
    return result
}
// console.log(methods3(arr))
// 4、includes 能区别NaN涉及到includes方法的底层实现
function methods4(arr) {
    const result = []
    arr.forEach(item => {
        if(!result.includes(item)) {
            result.push(item)
        }
    })
    return result
}
// console.log(methods4(arr))
// 5、filter+indexOf
// 这个会去掉所有的NaN，indexOf(NaN)恒等于-1
function methods5(arr) {
    return arr.filter((item, index) => {
        return arr.indexOf(item) === index
    })
}
// console.log(methods5(arr))
// 6、利用Map  可以去NaN
function methods6(arr) {
    const map = new Map()
    const result = []
    arr.forEach(item => {
        if(!map.has(item)) {
            map.set(item, true)
            result.push(item)
        }
    })
    return result
}
// console.log(methods6(arr))
// 7、利用对象，原理类似map，能去对象
// 因为obj的key都会转为string，所以有'[object Object]' == '[object Object]'
// 'NaN' == 'NaN'
function methods7(arr) {
    let obj = {}
    let result = []
    arr.forEach(item => {
        if(!obj[item]) {
            obj[item] = true
            result.push(item)
        }
    })
    return result
}
console.log(methods7(arr))